#!/usr/bin/env python3
import os
import re
from markup import *

#WARNING: if you're going to use special characters like emojis, type them as HTML entities!
def build_entry_html_truncated(entry_id,entry_title,entry_date,entry_body):
	entry_body = entry_truncate(entry_body,entry_id)
	return """<article id="%s">
<a name="entry_%s"></a>
<h1 class="article-header">&#128196;&nbsp;<a href="articles/%s.html">%s</a></h1>
<span class="metadata">%s</span><br>
%s
</article>
""" % (entry_id,entry_id,entry_id,entry_title,entry_date,entry_body)

def build_entry_html(entry_title,entry_date,entry_body):
	return """<!-- !!TITLE:%s -->
<h1 class="article-header">%s</h1>
<p class="metadata">%s</p>
<!-- !!ARTICLE BODY -->
%s
<!-- !!END -->
""" % (entry_title,entry_title,entry_date,entry_body)

def build_entry_xml(entry_id,entry_date,neocities_username,entry_html_body):
	entry_desc = entry_truncate(entry_html_body,entry_id)
	entry_desc = entry_desc.replace('<','&lt;').replace('>','&gt;')

	return """<item>
<guid>%s</guid>
<title>New entry on %s.neocities.org</title>
<pubDate>%s</pubDate>
<description>
%s
</description>
<link>https://%s.neocities.org/%s.html#entry_%s</link>
</item>
""" % (entry_id,neocities_username,entry_date,entry_desc,neocities_username,blog_fname,entry_id)

def entry_truncate(str,entry_id):
	#truncates article preview to only the first paragraph, if no paragraphs (<p></p>), the whole entry is returned
	truncated=""
	paragraphs=str.split("</p>")
	if paragraphs.__len__ == 1:
		truncated=str+"<nav class=\"entrynav\"><a href=\"#entry_"+entry_id+"\">Permalink</a> | <a href=\"#top\">Top</a>  | <a href=\"articles/"+entry_id+".html\">Full entry &#187;</a></nav><br>"
	else:
		truncated=paragraphs[0]+"</p><nav class=\"entrynav\"><a href=\"#entry_"+entry_id+"\">Permalink</a> | <a href=\"#top\">Top</a>  | <a href=\"articles/"+entry_id+".html\">Full entry &#187;</a></nav><br>"
	return truncated

def insert_article(entry_html_body, entry_xml_body):
	#insert an article into html
	blog_html = open("public_html/"+blog_fname+".html").read()
	#this is the reason why you shouldn't delete <!-- COMMENTS -->, they are used to insert entries
	blog_html_split = blog_html.split("<!-- !!BLOG ENTRIES -->\n")
	#split blog html and insert new article
	blog_html_top = blog_html_split[0]
	blog_html_bottom = blog_html_split[1]

	blog_html_new = blog_html_top+"<!-- !!BLOG ENTRIES -->\n"+entry_html_body+blog_html_bottom
	#temporary delete blog html and re-write it with new contents
	os.system("rm -f public_html/"+blog_fname+".html")
	os.system("touch public_html/"+blog_fname+".html")
	open("public_html/"+blog_fname+".html","w").write(blog_html_new)


	#now let's insert the article into rss feed! :3
	blog_rss = open("public_html/rss.xml").read()
	#split the file
	blog_rss_split = blog_rss.split("<!-- !!BLOG ENTRIES -->\n")
	blog_rss_top = blog_rss_split[0]
	blog_rss_bottom = blog_rss_split[1]

	blog_rss_new = blog_rss_top+"<!-- !!BLOG ENTRIES -->\n"+entry_xml_body+blog_rss_bottom
	#let's delete and re-write again...
	os.system("rm -f public_html/rss.xml")
	os.system("touch public_html/rss.xml")
	open("public_html/rss.xml","w").write(blog_rss_new)

def create_article_file(entry_id,entry_title,entry_body_html):
	#read article template
	template_html = open("public_html/articles/article_template.html").read()
	template_html_split = template_html.split("<!-- !!ARTICLE -->\n")
	template_html_top=template_html_split[0]
	template_html_bottom=template_html_split[1]

	#insert article
	html_pre = template_html_top+"<!-- !!ARTICLE -->\n"+entry_body_html+template_html_bottom
	#insert <title>
	html_pre_split = html_pre.split("<title>")
	html_pre_top = html_pre_split[0]
	html_pre_bottom = html_pre_split[1]

	article_html = html_pre_top+"<title>"+entry_title+html_pre_bottom

	#create the new entry file! :3
	os.system("touch public_html/articles/"+entry_id+".html")
	open("public_html/articles/"+entry_id+".html","w").write(article_html)

def add_new_entries(blog_fname):
	#count added entries
	added=0
	#read current html contents from blog file
	blog_html = open("public_html/"+blog_fname+".html").read()
	#count existing entries
	html_current_entries = re.findall("<article id=\"" + r"[0-9]+" + "\">",blog_html)
	html_entries_count = html_current_entries.__len__()
	#count entry files in "entries/" directory
	raw_entries_files = sorted(os.listdir("entries/"))
	raw_entries_count = raw_entries_files.__len__()-1 #exclude "README" file

	if raw_entries_count > html_entries_count:
		for fname in raw_entries_files:
			if fname=="README":
				continue
			entry_id=fname.split('_')[1]
			entry_raw=open("entries/"+fname).read()

			if entry_raw == "[DELETED]\n" or html_current_entries.count("<article id=\""+entry_id+"\">") > 0:
				continue

			entry_title=entry_raw.split('\n')[0].split("TITLE:")[1].replace('<','&lt;').replace('>','&gt;')
			entry_date=entry_raw.split('\n')[1].split("DATE:")[1]
			entry_body_raw=entry_raw.split("BODY:\n")[1]
			entry_body_html=mdtohtml(entry_body_raw)

			#build "final product"
			neocities_username=open("nci.conf").read().split('\n')[0]

			entry_full_html=build_entry_html(entry_title,entry_date,entry_body_html)
			entry_truncated_html=build_entry_html_truncated(entry_id,entry_title,entry_date,entry_body_html)
			entry_full_xml=build_entry_xml(entry_id,entry_date,neocities_username,entry_body_html)

			#insert data
			insert_article(entry_truncated_html,entry_full_xml)
			create_article_file(entry_id,entry_title,entry_full_html)

def del_entries(blog_fname):
	#count deleted entries
	deleted=0
	#check if any raw entry is [DELETED]
	raw_entries_files=sorted(os.listdir("entries/"))
	raw_entries_count=raw_entries_files.__len__()

	for fname in raw_entries_files:
		if fname == "README":
			continue #exclude README file
		entry_id=fname.split("_")[1]
		entry_raw=open("entries/"+fname).read()

		#check if entry is deleted but still exists in public_html
		if entry_raw=="[DELETED]\n":
			#delete article page, if file not found, nothing will happen so thanks -f
			os.system("rm -f public_html/articles/"+entry_id+".html")

			#check if entry still exists in html or rss files and remove it from them if so
			blog_html=open("public_html/"+blog_fname+".html").read()
			html_current_entries=re.findall("<article id=\""+r"[0-9]+"+"\">",blog_html)

			#i suck at html DOM manipulation using python
			if html_current_entries.count("<article id=\""+entry_id+"\">") > 0:
				blog_html_split = blog_html.split("<article id=\""+entry_id+"\">")
				blog_html_top = blog_html_split[0]

				blog_html_pre_bottom = blog_html_split[1]
				blog_html_bottom = blog_html_pre_bottom[blog_html_pre_bottom.find("</article>")+10:]

				blog_html_new = blog_html_top+blog_html_bottom
				os.system("rm -f public_html/"+blog_fname+".html")
				os.system("touch public_html/"+blog_fname+".html")
				open("public_html/"+blog_fname+".html","w").write(blog_html_new)

			#delete from rss xml
			blog_rss_xml = open("public_html/rss.xml").read()
			rss_current_entries = re.findall("<guid>"+r"[0-9]+"+"</guid>",blog_rss_xml)

			if rss_current_entries.count("<guid>"+entry_id+"</guid>")>0:
				blog_rss_split = blog_rss_xml.split("<item>\n<guid>"+entry_id+"</guid>")
				blog_rss_top = blog_rss_split[0]

				blog_rss_pre_bottom = blog_rss_split[1]
				blog_rss_bottom = blog_rss_pre_bottom[blog_rss_pre_bottom.find("</item>")+7:]

				blog_rss_new = blog_rss_top+blog_rss_bottom
				os.system("rm -f public_html/rss.xml")
				os.system("touch public_html/rss.xml")
				open("public_html/rss.xml","w").write(blog_rss_new)

def update_entries(blog_fname):
	#count updated entries
	updated=0
	html_articles = sorted(os.listdir("public_html/articles/"))

	#read excluded entries
	excluded_raw = ""
	to_exclude = []

	try:
		excluded_raw = open("exclude.conf").read()
	except FileNotFoundError:
		print("[!] Warning: exclude.conf file not found.")

	to_exclude = excluded_raw.split('\n')

	#compare html content with mdtohtml(raw) for each existing non-deleted entry
	for f_article in html_articles:
		if f_article == "article_template.html" or f_article == "style.css":
			continue

		entry_id = f_article.split(".html")[0]
		entry_page = open("public_html/articles/"+f_article).read()

		if str(entry_id) in to_exclude:
			print("[*] Entry No. "+entry_id+" excluded from being updated.")
			continue


		entry_title = entry_page.split("<!-- !!TITLE:")[1].split(" -->")[0]
		html_split = entry_page.split("<!-- !!ARTICLE BODY -->\n")
		html_top = html_split[0]
		entry_body = html_split[1]
		html_split2 = entry_body.split("<!-- !!END -->\n")
		entry_body = html_split2[0]
		html_bottom = html_split2[1]

		entry_new_title = open("entries/entry_"+entry_id).read().split('\n')[0].split("TITLE:")[1].replace('<',"&lt;").replace('>',"&gt;")
		entry_new_body = mdtohtml(open("entries/entry_"+entry_id).read().split('BODY:\n')[1])
		#DATES CAN'T BE CHANGED (NO SUPPORT FOR THAT)! DO NOT TRY TO "UPDATE" YOUR ENTRIES POST DATE.
		entry_date = open("entries/entry_"+entry_id).read().split('\n')[1].split("DATE:")[1]

		if entry_body != entry_new_body or entry_title != entry_new_title:
			#modify blog html
			bhtml = open("public_html/"+blog_fname+".html").read()
			bhtml_split = bhtml.split("<article id=\""+entry_id+"\">\n")
			bhtml_top = bhtml_split[0]
			bhtml_entry_start = bhtml_split[1]
			bhtml_bottom = bhtml_entry_start[bhtml_entry_start.find("</article>")+10:]

			entry_new_html = build_entry_html_truncated(entry_id, entry_new_title, entry_date, entry_new_body)

			bhtml_new = bhtml_top+entry_new_html+bhtml_bottom
			os.system("rm -f public_html/"+blog_fname+".html")
			os.system("touch public_html/"+blog_fname+".html")
			open("public_html/"+blog_fname+".html","w").write(bhtml_new)

			#modify rss
			blog_rss_xml = open("public_html/rss.xml").read()

			blog_rss_split = blog_rss_xml.split("<item>\n<guid>"+entry_id+"</guid>")
			blog_rss_top = blog_rss_split[0]
			blog_rss_entry_start = blog_rss_split[1]
			blog_rss_bottom = blog_rss_entry_start[blog_rss_entry_start.find("</item>")+7:]

			username=open("nci.conf").read().split('\n')[0]
			entry_new_xml = build_entry_xml(entry_id,entry_date,username,entry_new_body)

			blog_rss_new_xml = blog_rss_top+entry_new_xml+blog_rss_bottom
			os.system("rm -f public_html/rss.xml")
			os.system("touch public_html/rss.xml")
			open("public_html/rss.xml","w").write(blog_rss_new_xml)

			#modify entry page
			article_html_new = html_top.replace(entry_title,entry_new_title)+"<!-- !!ARTICLE BODY -->\n"+entry_new_body+"<!-- !!END -->\n"+html_bottom
			os.system("rm -f public_html/articles/"+entry_id+".html")
			os.system("touch public_html/articles/"+entry_id+".html")
			open("public_html/articles/"+entry_id+".html","w").write(article_html_new)

#...
print("Updating blog public files...")
#read blog filename from configuration file
blog_fname = open("nci.conf").read().split('\n')[1]

#update
add_new_entries(blog_fname)
del_entries(blog_fname)
update_entries(blog_fname)

print("Files successfully updated! IMPORTANT: Remember to run the \"./push\" command to upload your changed files to Neocities.")
print("OK.")
